
package com.ctrip.corp.obt.shard.sql.parser.tenant;


import com.ctrip.corp.obt.generic.core.context.TenantContext;
import com.ctrip.corp.obt.generic.utils.StringUtils;
import com.ctrip.corp.obt.shard.configuration.DataShardProperties;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.StringValue;

import java.util.Optional;

/**
 * 租户处理器（ TenantId 行级 ）
 *
 * @author marco.zheng
 * @since 2022-02-10
 */
@Slf4j
@RequiredArgsConstructor
public class DefaultTenantHandler implements TenantHandler {

    private final DataShardProperties dataShardProperties;

    /**
     * 获取租户 ID 值表达式，支持多个 ID 条件查询
     * <p>
     * 支持自定义表达式，比如：tenant_id in (1,2) @since 2019-8-2
     *
     * @return 租户 ID 值表达式
     */
    public Expression getTenantId() {
        // TODO 后面需要考虑此处逻辑如何处理比较好，非Saas场景的客户，用不上TenantHandler
        // 设置当前租户ID，实际情况你可以从cookie、或者缓存中拿都行。匹配数据库中的数据
        String tenantId = Optional.ofNullable(TenantContext.getTenantId()).orElse(StringUtils.EMPTY);
        return new StringValue(tenantId);
    }

    /**
     * 获取租户字段名
     *
     * @return 租户字段名
     */
    public String getTenantIdColumn() {
        // 对应数据库租户ID的列名，是数据库列名，不是实体类
        return dataShardProperties.getTenantIdColumn();
    }

    /**
     * 根据表名判断是否进行过滤
     *
     * @param tableName 表名
     * @return 是否进行过滤, true:表示忽略，false:需要解析多租户字段
     */
    public boolean ignoreTable(String tableName) {
        // 是否需要需要过滤某一张表，false为不过滤
        return dataShardProperties.isFilterTable(tableName);
    }
}
